#include <heatmap.h>

HeatMap::HeatMap(QWidget *parent) : QWidget(parent)
{
	matrix = NULL;
	network = NULL;
	//timer = new CPrecisionTimer();
	im = NULL;
	setMouseTracking(true);
}

HeatMap::~HeatMap(void)
{
}

void HeatMap::setMatrix(CorrelationMatrix *matr)
{
	if(matrix!=matr)
	{
		matrix = matr;
		recreate();
	}
	else
		recreate();
}

void HeatMap::setNetwork(FunctionalNetwork *netw)
{
	network = netw;
}

void HeatMap::paintEvent(QPaintEvent *evt)
{
    if(!matrix)
        return;

	if(!im)
		recreate();

	QPainter painter(this);
	painter.drawImage(QRectF(0,0,width(),height()),*im);
	
	QWidget::paintEvent(evt);
}

void HeatMap::mouseMoveEvent(QMouseEvent *ev)
{
	if(!matrix)
		return;

	double w = (double)width();
	double h = (double)height();
	double x = (double)ev->x();
	double y = (double)ev->y();
	int px = (int)floor((((double)matrix->width()+1)/w)*x);
	int py = (int)floor((((double)matrix->height()+1)/h)*y);
	//if(px >= py) //only upper triangle
		emit elementSelected(py,px);
}

void HeatMap::createLookupMatrix(){
	int x;
	int y;
	
	if(lookupMatrix.size() == 0){
		for(int i = 0; i<(int)matrix->height();i+=2){
			QVector<QPoint*> row;
			for(int j = 0; j<(int)matrix->width();j+=2){
				if(i > j){
					int tmp = i;
					x = j;
					y = tmp;
				}else{x = i; y =j;} 
				QPoint *p = new QPoint(x,y);
				row.push_back(p);
			}
			for(int j = (int)matrix->width()-1; j>=0;j-=2){
				if(i > j){
					int tmp = i;
					x = j;
					y = tmp;
				}else{x = i; y =j;}
				QPoint *p = new QPoint(x,y);
				row.push_back(p);
			}
			lookupMatrix.push_back(row);
		}
		for(int i = (int)matrix->width()-1; i>=0;i-=2){
			QVector<QPoint*> row;
			for(int j = 0; j<(int)matrix->width();j+=2){
				if(i > j){
					int tmp = i;
					x = j;
					y = tmp;
				}else{x = i; y =j;}
				QPoint *p = new QPoint(x,y);
				row.push_back(p);
			}
			for(int j = (int)matrix->width()-1; j>=0;j-=2){
				if(i > j){
					int tmp = i;
					x = j;
					y = tmp;
				}else{x = i; y =j;}
				QPoint *p = new QPoint(x,y);
				row.push_back(p);
			}
			lookupMatrix.push_back(row);
		}
	}
}

QVector< QVector<QPoint*> > HeatMap::getLookupMatrix(){
	return lookupMatrix;
}

CorrelationMatrix* HeatMap::getMatrix(){
	return matrix;
}

void HeatMap::mousePressEvent(QMouseEvent *ev){
	if(!matrix)
		return;
		
	double w = (double)width();
	double h = (double)height();
	double x = (double)ev->x();
	double y = (double)ev->y();
	int px = (int)floor((((double)matrix->width()+1)/w)*x);
	int py = (int)floor((((double)matrix->height()+1)/h)*y);
	//if(px >= py)
		emit elementClicked(py,px);
}

void HeatMap::updateSelection()
{
	
}



void HeatMap::recreate()
{


	if(lookupMatrix.size() == 0)
		createLookupMatrix();
	
	if(im)
		im->~QImage();  //destroy
	im = new QImage(matrix->width()+1,matrix->height()+1,QImage::Format_ARGB32_Premultiplied); //+1 so we can highlight
	
	QPainter painter(im);
	QColor c(0.93*255,0.93*255,0.93*255);// = QApplication::palette().color(QPalette::Window);
	painter.setBackground(QBrush(c));

	for(int i = 0;i<(int)lookupMatrix.at(0).size();i++)
	{
		for(int j = i;j<(int)lookupMatrix.at(0).size();j++)
		{
			if(!(i==0 && j==0)){ // TODO: fix getLink(0,0)
				//timer->Start();
				QPoint *point = lookupMatrix.at(i).at(j);
				int x = point->x();
				int y = point->y();
				AnatomicalLink *link = network->getLink(x,y);
				if(link->isEnabled()){
					// Pixmap values depend on slider setting
					double corr = matrix->at(x,y);
					double rgb[3] = {0, 0, 0};
					//LUT_Linear_Heat()->GetColor(corr,rgb);
					ColorMap::getInstance()->getLookupTable()->GetColor(corr,rgb);
					im->setPixel(j,i+1,qRgb(rgb[0]*255,rgb[1]*255,rgb[2]*255)); //i+1 we skip the first row for highlighting
					
					//and highlight
					int amount = network->getSelection().count();
					if(network->getSelection().contains(link) && i <= j)
					{
						int t = matrix->width();
						im->setPixel(t,(i+1),qRgb(0,0,0));
						im->setPixel(j,0,qRgb(0,0,0));
					}
				}
			}else{
				double rgb[3] = {0, 0, 0};
				ColorMap::getInstance()->getLookupTable()->GetColor(1.0,rgb);
				im->setPixel(j,i+1,qRgb(rgb[0]*255,rgb[1]*255,rgb[2]*255));
			}

		}
	}
	
	
	

	
	update();
}
